package com.iplant.aps.serviceImpl.utils.aps;

import com.iplant.aps.service.po.oms.OMSOrder;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.Configuration;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.basic.service.basicenum.bfc.FMCShiftType;
import com.iplant.basic.service.basicenum.bms.BMSDepartmentType;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.basic.service.basicenum.bms.BMSFunctionType;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.cfg.CFGCalendar;
import com.iplant.basic.service.po.fmc.FMCShift;
import com.iplant.basic.service.po.fmc.FMCTimeZone;
import com.iplant.basic.service.po.fmc.FMCWorkshop;
import com.iplant.basic.utils.Constants;
import com.iplant.pdm.service.basicenum.fpc.FPCRouteType;
import com.iplant.pdm.service.po.bop.FPCRoutePart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 排程服务工具类
 *
 * @author PengYouWang
 * 2020-1-9 15:19:23
 */
public class APSUtils {
    private static final Logger logger = LoggerFactory.getLogger(APSUtils.class);

    public APSUtils() {
    }

    private static APSUtils Instance;

    public static APSUtils getInstance() {
        if (Instance == null)
            Instance = new APSUtils();
        return Instance;
    }

    //region POService
    PoService<CFGCalendar> mCFGCalendarService = ORMUtils.GetPoService(CFGCalendar.class);
    PoService<FMCWorkshop> mFMCWorkshopService = ORMUtils.GetPoService(FMCWorkshop.class);
    PoService<FMCShift> mFMCShiftService = ORMUtils.GetPoService(FMCShift.class);
    //endregion




    /**
     * UTC时间转本地时间
     */
    public Calendar UtcToLocal(Calendar wUTCCalendar) {
        Calendar wResult = Calendar.getInstance();
        try {
            Date wDate = UtcToLocal(wUTCCalendar.getTime());
            wResult.setTime(wDate);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * UTC时间转本地时间
     */
    public Date UtcToLocal(Date wUtcDate) {
        Date wLocalDate = new Date();
        try {
            long wUtcTimeInMillis = wUtcDate.getTime();
            Calendar wCalendar = Calendar.getInstance();
            wCalendar.setTimeInMillis(wUtcTimeInMillis);
            /* 取得时间偏移量 */
            int wZoneOffset = wCalendar.get(Calendar.ZONE_OFFSET);
            /* 取得夏令时差 */
            int wDstOffset = wCalendar.get(Calendar.DST_OFFSET);
            /* 从本地时间里扣除这些差量，即可以取得UTC时间 */
            wCalendar.add(Calendar.MILLISECOND, (wZoneOffset + wDstOffset));
            /* 取得的时间就是UTC标准时间 */
            wLocalDate = new Date(wCalendar.getTimeInMillis());
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wLocalDate;
    }



    /**
     * 获取日期所在月最后一天
     */
    public Calendar getLastDayOfMonth(Calendar wDate) {
        Calendar wResult = Calendar.getInstance();
        try {
            wResult = wDate;
            int wLast = wResult.getActualMaximum(Calendar.DAY_OF_MONTH);
            wResult.set(Calendar.DAY_OF_MONTH, wLast);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取指定日期所在周最后一天
     */
    public Calendar getLastOfWeek(Calendar wDate) {
        Calendar wResult = Calendar.getInstance();
        try {
            int wD = 0;
            if (wDate.get(Calendar.DAY_OF_WEEK) == 1) {
                wD = -6;
            } else {
                wD = 2 - wDate.get(Calendar.DAY_OF_WEEK);
            }
            wDate.add(Calendar.DAY_OF_WEEK, wD);
            wDate.add(Calendar.DAY_OF_WEEK, 6);
            wResult = wDate;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 根据年 月 获取对应的月份 天数
     */
    public int getDaysByYearMonth(int wYear, int wMonth) {
        Calendar wDate = Calendar.getInstance();
        wDate.set(Calendar.YEAR, wYear);
        wDate.set(Calendar.MONTH, wMonth - 1);
        wDate.set(Calendar.DATE, 1);
        wDate.roll(Calendar.DATE, -1);
        return wDate.get(Calendar.DATE);
    }

    /**
     * 计算开始时间和结束时间之间的间隔小时
     *
     * @param wStartTime 开始时间
     * @param wEndTime   结束时间
     * @return 间隔小时
     */
    public double CalIntervalHour(Calendar wStartTime, Calendar wEndTime) {
        double wResult = 0.0;
        try {
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1);
            if (wStartTime == null) {
                wStartTime = wBaseTime;
            }
            if (wEndTime == null) {
                wEndTime = wBaseTime;
            }
            if (wStartTime.compareTo(wEndTime) >= 0) {
                return wResult;
            }

            long wStart = wStartTime.getTime().getTime();
            long wEnd = wEndTime.getTime().getTime();
            long wMinutes = (wEnd - wStart) / (1000 * 60);
            double wHour = (double) wMinutes / 60;
            wResult = formatDouble(wHour);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 计算开始时间和结束时间之间的间隔天数
     *
     * @param wStartTime 开始时间
     * @param wEndTime   结束时间
     * @return 间隔天数
     */
    public int CalIntervalDays(Calendar wStartTime, Calendar wEndTime) {
        int wResult = 0;
        try {
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1);
            if (wStartTime == null) {
                wStartTime = wBaseTime;
            }
            if (wEndTime == null) {
                wEndTime = wBaseTime;
            }
            if (wStartTime.compareTo(wEndTime) >= 0) {
                return wResult;
            }

            long wStart = wStartTime.getTime().getTime();
            long wEnd = wEndTime.getTime().getTime();
            long wMinutes = (wEnd - wStart) / (1000 * 60);
            wResult = (int) (wMinutes / 60 / 24);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 四舍五入保留两位小数
     */
    public double formatDouble(double wNumber) {
        double wResult = 0.0;
        try {
            // 如果不需要四舍五入，可以使用RoundingMode.DOWN
            BigDecimal wBG = new BigDecimal(wNumber).setScale(2, RoundingMode.UP);
            wResult = wBG.doubleValue();
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取所有后续工艺集合
     */
    public List<Integer> GetNextPartIDList(int wRoutePartID, List<FPCRoutePart> wRoutePartList) {
        List<Integer> wResult = new ArrayList<>();
        try {
            if (wRoutePartList == null || wRoutePartList.size() == 0) {
                return wResult;
            }

            if (wRoutePartList.stream().noneMatch(p -> p.ID == wRoutePartID)) {
                return wResult;
            }
            // ①从集合中找到此PartID的RoutePart
            FPCRoutePart wRoutePart = wRoutePartList.stream().filter(p -> p.ID == wRoutePartID).findFirst().get();
            // ②根据nextPart找
            if (wRoutePart.NextPartIDMap != null && wRoutePart.NextPartIDMap.size() > 0) {
                for (String wKey : wRoutePart.NextPartIDMap.keySet()) {
                    int wTempID = Integer.parseInt(wKey);
                    if (wTempID <= 0) {
                        continue;
                    }
                    if (wResult.stream().anyMatch(p -> p == wTempID)) {
                        continue;
                    }
                    wResult.add(wTempID);
                    List<Integer> wList = GetNextPartIDList(wTempID, wRoutePartList);
                    if (wList != null && wList.size() > 0) {
                        wResult.addAll(wList);
                    }
                }
            }
            // ③根据Prev找
            List<FPCRoutePart> wRouteList = wRoutePartList.stream().filter(p -> p.PrevPartID == wRoutePartID)
                    .collect(Collectors.toList());
            if (wRouteList.size() > 0) {
                for (FPCRoutePart wTempRoute : wRouteList) {
                    if (wResult.stream().anyMatch(p -> p == wTempRoute.ID)) {
                        continue;
                    }

                    wResult.add(wTempRoute.ID);
                    List<Integer> wList = GetNextPartIDList(wTempRoute.ID, wRoutePartList);
                    if (wList != null && wList.size() > 0) {
                        wResult.addAll(wList);
                    }
                }
            }

            // 去除不合理的数据
            if (wResult.size() > 0) {
                wResult.removeIf(p -> p <= 0);

                wResult = wResult.stream().distinct().collect(Collectors.toList());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取SAP终结点地址
     */
    public String GetSAPEndpoint() {
        String wResult = "";
        try {
            String wSapIp = Configuration.readConfigString("sapip", "config/config");
            if (StringUtils.isEmpty(wSapIp))
                wResult = "http://10.200.10.12:8000/sap/bc/srt/rfc/sap/zif_mes_ws/120/zif_mes_ws/zif_mes_ws";
            else
                wResult = wSapIp;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取SAP用户名
     */
    public String GetSAPUser() {
        String wResult = "";
        try {
            String wSapIp = Configuration.readConfigString("sapuser", "config/config");
            if (StringUtils.isEmpty(wSapIp))
                wResult = "sapdev";
            else
                wResult = wSapIp;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取SAP密码
     */
    public String GetSAPPassword() {
        String wResult = "";
        try {
            String wSapIp = Configuration.readConfigString("sappassword", "config/config");
            if (StringUtils.isEmpty(wSapIp))
                wResult = "senchu2020";
            else
                wResult = wSapIp;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 根据型号、工位、职能 获取对应人员  //todo
     */
    public List<BMSEmployee> QueryFunctionEmployeeList(BMSEmployee wLoginUser, int wProductID, int wStationID, BMSFunctionType wBMSFunctionType) {
        List<BMSEmployee> wResult = new ArrayList<>();
        try {
            //根据班组

        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }






    //todo  QRCodeUtils
    public String getQRCodeString(BMSEmployee wLoginUser, String wText) {
        String wResult = "";
        try {
            // ②嵌入二维码的图片路径
            String imgPath = "";
            // ③文件名称
            String wFileName = UUID.randomUUID().toString().replaceAll("-", "");
            // ④生成的二维码的路径及名称
            String wDirePath = StringUtils.Format("{0}static/export/{1}.jpg",
                    Constants.getConfigPath().replace("config/", ""), wFileName);
            File wDirFile = new File(wDirePath);
            if (!wDirFile.exists()) {
                wDirFile.mkdirs();
            }
            // ⑥生成二维码
          //  QRCodeUtil.encode(wText, imgPath, wDirePath, true);
            // ⑦返回路径
            wResult = StringUtils.Format("/{0}/export/{1}.jpg",
                    Configuration.readConfigString("project.name", "application"), wFileName);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }

        return wResult;
    }


}
